package com.example.filter;

import com.example.utils.CurrentHolder;
import com.example.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;

/**
 * 令牌校验过滤器
 */
@Slf4j
@WebFilter(urlPatterns = "/*") // 拦截所有请求
public class TokenFilter implements Filter {

    /**
     * 初始化方法, 在过滤器初始化时执行,一般用于资源初始化
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    /**
     * 过滤器逻辑
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1. 获取请求路径
        String requestURI = request.getRequestURI();

        //2. 判断是否包含login,包含说明是登录操作,放行
        if (requestURI.contains("/login")) {
            log.info("登录操作,放行");
            filterChain.doFilter(request, response); // 放行
            return;
        }

        //3.获取请求头中的token
        String token = request.getHeader("token");

        //4. 判断token是否存在,如果不存在,说明未登录,返回错误信息
        if(token == null||token.isEmpty()){
            log.info("令牌为空,未登录");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);// 401
            return;
        }

        //5.如果存在,校验令牌是否正确,正确放行,错误返回错误信息
        try {
            Claims claims = JwtUtils.parseToken(token);//解析令牌
            Integer empId = (Integer) claims.get("id");//从令牌中获取员工id
            CurrentHolder.setCurrentId(empId);//将empId存入ThreadLocal中
            log.info("当前员工ID{},存入ThreadLocal中", empId);
        } catch (Exception e) {
            log.info("令牌非法,响应401");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);// 401
            return;
        }

        //6.校验通过,放行
        log.info("令牌校验通过,放行");
        filterChain.doFilter(request, response); // 放行

        //7.删除当前线程ThreadLocal中的数据
        CurrentHolder.remove();

    }

    /**
     * 销毁方法, 在过滤器销毁时执行,一般用于资源销毁
     */
    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
